package org.bulu.project.system.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.Month;
import lombok.extern.slf4j.Slf4j;
import org.bulu.project.common.result.Result;
import org.bulu.project.system.mapper.UserVideoMapper;
import org.bulu.project.system.mapper.VideoMapper;
import org.bulu.project.system.mapper.VideoStatsMapper;
import org.bulu.project.system.model.dto.VideoUploadInfoDTO;
import org.bulu.project.system.model.entity.Video;
import org.bulu.project.system.model.entity.VideoStats;
import org.bulu.project.system.security.SecurityUtils;
import org.bulu.project.system.service.VideoUploadService;
import org.bulu.project.system.util.OssUtil;
import org.bulu.project.system.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;

import static java.util.concurrent.TimeUnit.*;

@Slf4j
@Service
public class VideoUploadServiceImpl implements VideoUploadService {
    @Autowired
    private VideoMapper videoMapper;
    @Autowired
    private VideoStatsMapper videoStatsMapper;
    @Autowired
    private OssUtil ossUploadUtil ;//oss工具类
    @Autowired
    private UserVideoMapper userVideoMapper;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    @Qualifier("taskExecutor")
    private Executor taskExecutor;

    /*
        添加投稿
        @param cover 封面
        @param videoUploadInfoDTO 视频信息
     */
    @Transactional
    @Override
    public Result addVideo(Video video){
        //获取用户Id
        Long userId = SecurityUtils.getUserId();

         //将投稿信息封装
        video.setUid(userId);
        //获取当前时间用datetime
        video.setCreateDate(DateUtil.date(new java.util.Date()));
        //添加语句之后返回vid的值
        Integer result = videoMapper.addVideo(video);
        if (result<=0){
            return Result.failed("false");
        }

        //新增VideoStatus数据
        VideoStats videoStats = new VideoStats();
        videoStats.setVid(Math.toIntExact(video.getVid()));
        videoStats.setPlay(0);
        videoStats.setGood(0);
        videoStats.setBad(0);
        videoStats.setCoin(0);
        videoStats.setCollect(0);
        videoStats.setDanmu(0);
        videoStats.setShare(0);
        videoStats.setComment(0);
        Integer isInsert = videoStatsMapper.insert(videoStats);
        //将数据存放在redis上
        CompletableFuture.runAsync(() -> redisUtil.setExValue("video:" + video.getVid(), video,30,DAYS),taskExecutor);
        CompletableFuture.runAsync(() -> redisUtil.addMember("video_status:0", video.getVid()), taskExecutor);
        CompletableFuture.runAsync(() -> redisUtil.setExValue("videoStats:" + videoStats.getVid(), videoStats,30, DAYS), taskExecutor);
        if(isInsert<=0){
            return Result.failed("false");
        }
        return Result.success("success");
    }

    /*
        根据本机路径上传视频返回上传后的地址
     */
    @Override
    public Result UploadVideo(MultipartFile file) {
        String url = ossUploadUtil.UploadVideo(file);
        if(url == null){
            return Result.failed("上传失败");
        }else {
            return Result.success(url);
        }
    }

    /*
        取消投稿时删除库的视频
     */
    @Override
    public Result DeleteVideo(String videoUrl) {
        boolean isDeletedFromOSS = ossUploadUtil.deleteFile(videoUrl);
        if (!isDeletedFromOSS) {
            return Result.failed("从OSS删除视频失败");
        }else{
            return Result.success("删除成功");
        }
    }

    /*
        根据视频id删除视频
        删除视频连带这跟这个视频有关的全部删除
     */
    @Transactional
    @Override
    public Result DeleteAllVideoInformation(Integer videoId) {
        Video video = videoMapper.findVideoById(videoId);
        if (video == null) {
            return Result.failed("视频不存在");
        }

        try {
            //删除OSS上的视频
            boolean isDeletedFromOSS = ossUploadUtil.deleteFile(video.getVideoUrl());
            if (!isDeletedFromOSS) {
                throw new RuntimeException("从OSS删除视频失败");
            }
            //设置数据库中video表的数据为已删除
            int deleteVideo = videoMapper.deleteVideo(videoId, DateUtil.date(new java.util.Date()));
            if (deleteVideo == 0) {
                throw new RuntimeException("从数据库删除视频失败");
            }
            //删除redis中video的数据
            redisUtil.delValue("video:" + videoId);
            //删除数据库中videostatu的数据
            int deleteVideoStats = videoStatsMapper.deleteById(videoId);
            if (deleteVideoStats == 0) {
                throw new RuntimeException("从数据库删除视频统计失败");
            }
            //删除redis中videostatu的数据
            redisUtil.delValue("videoStats:" + videoId);
            //删除redis中video待审核的数据
            redisUtil.delMember("video_status:0", videoId);
            //删除redis中video审核通过的数据
            redisUtil.delMember("video_status:1", videoId);
            //删除数据库中UserVideo的数据
            userVideoMapper.deleteUserVideo(videoId);
            return Result.success("删除成功!");
        } catch (Exception e) {
            log.error("删除视频时发生错误: {}", e.getMessage(), e);
            return Result.failed("删除失败: " + e.getMessage());
        }
    }

    @Override
    public Result uploadCover(MultipartFile file) {
        try{
            //保存封面到OSS,返回URL
            String coverUrl = ossUploadUtil.uploadImage(file, "cover");
            if(coverUrl==null){
                return Result.failed("封面上传失败");
            }
            return Result.success(coverUrl);
        }catch (Exception e){
            e.getMessage();
            return Result.failed("封面上传失败");
        }

    }
}
